/*
在未排序的数组中找到第 k 个最大的元素。请注意，你需要找的是数组排序后的第 k 个最大的元素，而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
说明:

你可以假设 k 总是有效的，且 1 ≤ k ≤ 数组的长度。

*/
#include <algorithm>
#include <queue>
#include <vector>
#include <iostream>

using namespace std;
/*
//1.最简单的方法：调用库函数排序
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        sort(nums.begin(),nums.end());
        return nums[nums.size()-k];
    }
};

//2.顶堆
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector<int>, greater<int>> q;
        int len=nums.size();
        for(int i=0;i<len;i++)
        {
            q.push(nums[i]);
            if(q.size()>k)
            {
                q.pop();
            }
        }
        return q.top();
    }
};
*/

//3.快速选择
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        int target= nums.size()-k;//转化为第k小问题
        int idx=0;
        int left=0;
        int right=nums.size()-1;
        while(true){
            idx=partition(nums,left,right);
            cout<<"idx:"<<idx<<endl;
            if(idx==target){
                return nums[idx];
            } else if(idx>target){
                right=idx-1;
            } else{
                left=idx+1;
            }  
        }
        return 0;
    }

//private:
    int partition(vector<int>& nums,int left,int right){
        int rand_pos=rand()%(right-left+1)+left;
        cout<<"random:"<<rand_pos<<endl;
        int pivot=nums[rand_pos];
        swap(nums,left,rand_pos);
        int j=left;
        for(int i=left+1;i<=right;i++){
            if(nums[i]<pivot){
                j++;
                swap(nums,i,j);
            }
        }
        swap(nums,left,j);
        return j;
    }

    void swap(vector<int>& nums,int i,int j){
        int tmp=nums[j];
        nums[j]=nums[i];
        nums[i]=tmp;
    }
};

int main()
{
    vector<int> vec_num{3,2,1,5,6,4};
    for (int i=0;i<vec_num.size();i++)
    {
        cout<<vec_num[i]<<endl;
    }
    Solution s;
    cout<<s.findKthLargest(vec_num,2)<<endl;
    for (int i=0;i<vec_num.size();i++)
    {
        cout<<vec_num[i]<<endl;
    }
    return 0;
}